﻿using System;
using System.Collections;
using System.Collections.Generic;
using Assets.Scripts.GtsScripts;
using UnityEngine;

// Token: 0x020002D1 RID: 721
[RequireComponent(typeof(MeshCollider))]
public class SkinnedMeshCollider : MonoBehaviour
{
	// Token: 0x060010CF RID: 4303 RVA: 0x0007B2AB File Offset: 0x000794AB
	private void Update()
	{
		if (this.hasInit && this.update && this.meshEnabled && this.skinnedMeshRenderer.isVisible)
		{
			base.StartCoroutine(this.UpdateDynamicMesh());
		}
	}

	// Token: 0x060010D0 RID: 4304 RVA: 0x0007B2EB File Offset: 0x000794EB
	public void SetPoseMode(bool value)
	{
		if (value)
		{
			this.layer = Layers.objectLayer;
		}
		else
		{
			this.layer = Layers.gtsBodyLayer;
		}
		this.UpdateLayer();
	}

	// Token: 0x060010D1 RID: 4305 RVA: 0x0007B320 File Offset: 0x00079520
	private void UpdateLayer()
	{
		foreach (KeyValuePair<int, GiantessBone> keyValuePair in this.giantessBones)
		{
			keyValuePair.Value.colliderFront.gameObject.layer = this.layer;
		}
	}

	// Token: 0x060010D2 RID: 4306 RVA: 0x0007B398 File Offset: 0x00079598
	public void Init(Giantess giantess)
	{
		this.layer = Layers.gtsBodyLayer;
		this.giantess = giantess;
		this.skinnedMeshRenderer = base.GetComponent<SkinnedMeshRenderer>();
		this.giantessBones = new Dictionary<int, GiantessBone>();
		base.gameObject.layer = Layers.objectLayer;
		this.poseMesh = new Mesh();
		this.poseMesh.MarkDynamic();
		base.StartCoroutine(this.InitializeDynamicMesh());
	}

	// Token: 0x060010D3 RID: 4307 RVA: 0x0007B406 File Offset: 0x00079606
	public void UpdateCollider()
	{
		this.update = true;
	}

	// Token: 0x060010D4 RID: 4308 RVA: 0x0007B410 File Offset: 0x00079610
	public void EnableCollision(bool value)
	{
		this.meshEnabled = value;
		foreach (KeyValuePair<int, GiantessBone> keyValuePair in this.giantessBones)
		{
			keyValuePair.Value.colliderFront.enabled = value;
		}
	}

	// Token: 0x060010D5 RID: 4309 RVA: 0x0007B480 File Offset: 0x00079680
	private IEnumerator InitializeDynamicMesh()
	{
		Mesh skinnedMesh = this.skinnedMeshRenderer.sharedMesh;
		BoneWeight[] boneWeights = skinnedMesh.boneWeights;
		Vector3[] vertices = skinnedMesh.vertices;
		Material[] materials = this.skinnedMeshRenderer.materials;
		int subMeshCount = Mathf.Min(materials.Length, skinnedMesh.subMeshCount);
		Transform[] boneTransforms = this.skinnedMeshRenderer.bones;
		this.boneIndex0 = new int[boneWeights.Length];
		for (int j = 0; j < this.boneIndex0.Length; j++)
		{
			this.boneIndex0[j] = boneWeights[j].boneIndex0;
		}
		this.boneData = new SkinnedMeshCollider.Bone[boneTransforms.Length];
		for (int k = 0; k < this.boneData.Length; k++)
		{
			SkinnedMeshCollider.Bone bone = new SkinnedMeshCollider.Bone();
			bone.transform = boneTransforms[k];
			bone.sharedTriangles = new List<int>[subMeshCount];
			bone.globalToLocalVertex = new int[vertices.Length];
			bone.vertexList = new List<int>();
			bone.trianglesArray = new int[subMeshCount][];
			for (int l = 0; l < subMeshCount; l++)
			{
				bone.sharedTriangles[l] = new List<int>();
			}
			bone.hasVertex = new bool[vertices.Length];
			this.boneData[k] = bone;
		}
		int[] boneAux = new int[3];
		for (int i = 0; i < subMeshCount; i++)
		{
			int[] subTriangles = skinnedMesh.GetTriangles(i);
			int totalFaces = subTriangles.Length / 3;
			for (int m = 0; m < totalFaces; m++)
			{
				int num = m * 3;
				int num2 = subTriangles[num];
				int num3 = subTriangles[num + 1];
				int num4 = subTriangles[num + 2];
				int num5 = this.boneIndex0[num2];
				int num6 = this.boneIndex0[num3];
				int num7 = this.boneIndex0[num4];
				int boneAuxCount = 1;
				boneAux[0] = num5;
				if (num5 != num6)
				{
					boneAux[1] = num6;
					if (num6 != num7)
					{
						boneAux[2] = num7;
						boneAuxCount = 3;
					}
					else
					{
						boneAuxCount = 2;
					}
				}
				else if (num5 != num7)
				{
					boneAux[1] = num7;
					boneAuxCount = 2;
				}
				for (int n = 0; n < boneAuxCount; n++)
				{
					SkinnedMeshCollider.Bone bone2 = this.boneData[boneAux[n]];
					bone2.sharedTriangles[i].Add(num2);
					bone2.sharedTriangles[i].Add(num3);
					bone2.sharedTriangles[i].Add(num4);
					if (!bone2.hasVertex[num2])
					{
						bone2.hasVertex[num2] = true;
						bone2.vertexList.Add(num2);
					}
					if (!bone2.hasVertex[num3])
					{
						bone2.hasVertex[num3] = true;
						bone2.vertexList.Add(num3);
					}
					if (!bone2.hasVertex[num4])
					{
						bone2.hasVertex[num4] = true;
						bone2.vertexList.Add(num4);
					}
				}
			}
			yield return null;
		}
		for (int num8 = 0; num8 < this.boneData.Length; num8++)
		{
			SkinnedMeshCollider.Bone bone3 = this.boneData[num8];
			bone3.vertexCount = bone3.vertexList.Count;
			bone3.vertexArray = bone3.vertexList.ToArray();
			bone3.localVertices = new Vector3[bone3.vertexCount];
			for (int num9 = 0; num9 < materials.Length; num9++)
			{
				bone3.trianglesArray[num9] = bone3.sharedTriangles[num9].ToArray();
			}
		}
		this.hasInit = true;
		this.UpdateCollider();
		yield break;
	}

	// Token: 0x060010D6 RID: 4310 RVA: 0x0007B49C File Offset: 0x0007969C
	private IEnumerator UpdateDynamicMesh()
	{
		this.update = false;
		yield return new WaitForSeconds(0.2f);
		Material[] materials = this.skinnedMeshRenderer.materials;
		int materialCount = materials.Length;
		bool[] isValidMaterial = new bool[materials.Length];
		for (int j = 0; j < materials.Length; j++)
		{
			if (materials[j].color.a > 0.05f)
			{
				isValidMaterial[j] = true;
			}
		}
		int bonesCount = this.boneData.Length;
		for (int k = 0; k < bonesCount; k++)
		{
			SkinnedMeshCollider.Bone bone2 = this.boneData[k];
			int num = 0;
			for (int l = 0; l < materialCount; l++)
			{
				if (isValidMaterial[l])
				{
					num += bone2.sharedTriangles[l].Count;
				}
			}
			bone2.localTriangles = new int[num];
		}
		for (int boneIndex = 0; boneIndex < bonesCount; boneIndex++)
		{
			if (!this.meshEnabled)
			{
				break;
			}
			SkinnedMeshCollider.Bone bone = this.boneData[boneIndex];
			if (bone.vertexCount != 0)
			{
				Vector3 position = base.transform.position;
				Quaternion rotation = base.transform.rotation;
				int localVertexIndex = 0;
				Transform boneTransform = bone.transform;
				Vector3 bonePosition = boneTransform.position;
				float inverseScale = 1f / boneTransform.lossyScale.y;
				Quaternion inverseRotation = Quaternion.Inverse(boneTransform.rotation);
				int vertexCount = bone.vertexCount;
				this.skinnedMeshRenderer.BakeMesh(this.poseMesh);
				Vector3[] vertices = this.poseMesh.vertices;
				for (int m = 0; m < vertexCount; m++)
				{
					int num2 = bone.vertexArray[m];
					Vector3 point = rotation * vertices[num2];
					point.x += position.x - bonePosition.x;
					point.y += position.y - bonePosition.y;
					point.z += position.z - bonePosition.z;
					point = inverseRotation * point;
					point.x *= inverseScale;
					point.y *= inverseScale;
					point.z *= inverseScale;
					bone.localVertices[localVertexIndex] = point;
					bone.globalToLocalVertex[num2] = localVertexIndex;
					localVertexIndex++;
				}
				int i = 0;
				for (int n = 0; n < materialCount; n++)
				{
					if (isValidMaterial[n])
					{
						int[] array = bone.trianglesArray[n];
						int num3 = array.Length;
						for (int num4 = 0; num4 < num3; num4++)
						{
							int num5 = array[num4];
							int num6 = bone.globalToLocalVertex[num5];
							bone.localTriangles[i] = num6;
							i++;
						}
					}
				}
				Mesh boneMesh = new Mesh();
				boneMesh.MarkDynamic();
				boneMesh.vertices = bone.localVertices;
				boneMesh.triangles = bone.localTriangles;
				boneMesh.name = "Mesh " + boneIndex;
				if (!this.giantessBones.ContainsKey(boneIndex))
				{
					Transform transform = bone.transform;
					Transform transform2 = new GameObject("Collider_" + transform.name).transform;
					transform2.gameObject.layer = this.layer;
					transform2.SetParent(transform, false);
					GiantessBone giantessBone = transform2.gameObject.AddComponent<GiantessBone>();
					giantessBone.Initialize(this.giantess);
					giantessBone.colliderFront = transform2.gameObject.AddComponent<MeshCollider>();
					giantessBone.colliderFront.sharedMesh = null;
					giantessBone.colliderFront.sharedMesh = boneMesh;
					this.giantessBones[boneIndex] = giantessBone;
				}
				else
				{
					GiantessBone giantessBone2 = this.giantessBones[boneIndex];
					giantessBone2.colliderFront.sharedMesh = null;
					giantessBone2.colliderFront.sharedMesh = boneMesh;
				}
				yield return null;
			}
		}
		yield return null;
		yield break;
	}

	// Token: 0x0400159E RID: 5534
	private SkinnedMeshRenderer skinnedMeshRenderer;

	// Token: 0x0400159F RID: 5535
	private Mesh poseMesh;

	// Token: 0x040015A0 RID: 5536
	private Giantess giantess;

	// Token: 0x040015A1 RID: 5537
	private Dictionary<int, GiantessBone> giantessBones;

	// Token: 0x040015A2 RID: 5538
	public bool update;

	// Token: 0x040015A3 RID: 5539
	private int[] boneIndex0;

	// Token: 0x040015A4 RID: 5540
	private SkinnedMeshCollider.Bone[] boneData;

	// Token: 0x040015A5 RID: 5541
	private bool meshEnabled = true;

	// Token: 0x040015A6 RID: 5542
	private bool hasInit;

	// Token: 0x040015A7 RID: 5543
	private LayerMask layer;

	// Token: 0x020002D2 RID: 722
	public class Bone
	{
		// Token: 0x040015A8 RID: 5544
		public Transform transform;

		// Token: 0x040015A9 RID: 5545
		public List<int>[] sharedTriangles;

		// Token: 0x040015AA RID: 5546
		public int[][] trianglesArray;

		// Token: 0x040015AB RID: 5547
		public int[] localTriangles;

		// Token: 0x040015AC RID: 5548
		public Vector3[] localVertices;

		// Token: 0x040015AD RID: 5549
		public List<int> vertexList;

		// Token: 0x040015AE RID: 5550
		public int[] vertexArray;

		// Token: 0x040015AF RID: 5551
		public int vertexCount;

		// Token: 0x040015B0 RID: 5552
		public bool[] hasVertex;

		// Token: 0x040015B1 RID: 5553
		public int[] globalToLocalVertex;
	}
}
